package cordova.plugin.audio;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.util.Log;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.apache.cordova.camera.FileHelper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * @author mj
 *         created at 2016/6/13
 */
public class audio extends CordovaPlugin {

    public static final String PLAY = "playAudio";  //播放
    public static final String STOP = "stopAudio";  //停止
    public static final String START_RECORD = "startRecordingAudio";  //开始录制
    public static final String STOP_RECORD = "stopRecordingAudio";  //停止录制
    private static Activity cordovaActivity;

    private MediaRecorder recorder;
    private MediaPlayer mPlayer;
    private String fileUriStr, audioFilePath;
    private boolean isRecording;
    private CallbackContext mCallbackContext;

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
        cordovaActivity = cordova.getActivity();
    }

    @Override
    public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        mCallbackContext = callbackContext;
        if (action.equals(START_RECORD)) {    //开始录制
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    callbackContext.sendPluginResult(startRecordingAudio());
                }
            });
        } else if (action.equals(STOP_RECORD)) {   //停止录制
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    callbackContext.sendPluginResult(stopRecordingAudio(args));
                }
            });
        } else if (action.equals(PLAY)) {    //播放
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    callbackContext.sendPluginResult(playAudio(args));
                }
            });
        } else {   //停止
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    callbackContext.sendPluginResult(stopAudio());
                }
            });
        }

        return true;
    }

    /**
     * 准备录制
     */
    private void prepareRecordingAudio() {

        stop();
        // stopRecordingAudio();
        if (mPlayer != null && mPlayer.isPlaying()) {
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
        }

        if (recorder == null) {
            recorder = new MediaRecorder();

            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            recorder.setAudioChannels(1);
        }

        String sdcardPath = "";
        if (isExternalStorageWritable()) {
            sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        } else {
            sdcardPath = Environment.getDataDirectory().getAbsolutePath();
        }
        String recordingDirectory = sdcardPath + File.separator + cordovaActivity.getPackageName();
        File dir = new File(recordingDirectory);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        fileUriStr = dir.getAbsolutePath() + File.separator + new Date().getTime() + ".amr";
        recorder.setOutputFile(FileHelper.stripFileProtocol(fileUriStr));

    }

    /**
     * 开始录制
     */
    private PluginResult startRecordingAudio() {
        prepareRecordingAudio();

        try {
            recorder.prepare();
            recorder.start();
        } catch (IllegalStateException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        isRecording = true;

        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject();
            jsonObject.put("message", "录制成功");
            jsonObject.put("code", 200);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return new PluginResult(PluginResult.Status.OK, jsonObject);
    }


    private void stop(){
        if (recorder != null && isRecording) {
            try {
                recorder.stop();
                isRecording = false;
                recorder.release();
                recorder = null;
            } catch (RuntimeException e) {
//                Log.v("stopRecordingAudio", "55555555555555");
                new File(fileUriStr).delete();
            }
        }
    }

    /**
     * 停止录制
     */
    private PluginResult stopRecordingAudio(JSONArray args) {
        stop();

        JSONObject jsonObject = null;
        try {
            JSONObject json = new JSONObject(args.getString(0));
            int time = json.getInt("time");
            jsonObject = new JSONObject();
            jsonObject.put("message", "停止录制成功");
            jsonObject.put("url", fileUriStr);
            jsonObject.put("time", time);
            jsonObject.put("code", 200);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return new PluginResult(PluginResult.Status.OK, jsonObject);
    }


    /**
     * 播放录音
     *
     * @param data
     * @return
     */
    private PluginResult playAudio(JSONArray data) {
        if (mPlayer != null && mPlayer.isPlaying()) {
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
        }
        mPlayer = new MediaPlayer();

        try {
            JSONObject jsonObject = new JSONObject(data.getString(0));
            String source = jsonObject.getString("url");
            mPlayer.setDataSource(source);
            mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mPlayer.start();
                }
            });
            mPlayer.prepareAsync();
            mPlayer.setOnCompletionListener(mOnCompletionListener);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject();
            jsonObject.put("message", "播放成功");
            jsonObject.put("code", 200);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return new PluginResult(PluginResult.Status.OK, jsonObject);
    }

    private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            Log.v("OnCompletionListener", "播放完成");
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject();
                jsonObject.put("message", "播放完成");
                jsonObject.put("code", 200);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            mCallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, jsonObject));
        }
    };


    /**
     * 停止播放
     *
     * @return
     */
    private PluginResult stopAudio() {
        if (mPlayer != null) {
            if (mPlayer.isPlaying()) {
                mPlayer.stop();
                mPlayer.release();
                mPlayer = null;
            }
        }

        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject();
            jsonObject.put("message", "停止播放成功");
            jsonObject.put("code", 200);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return new PluginResult(PluginResult.Status.OK);
    }

    /**
     * 判断是否有外部存储空间
     *
     * @return
     */
    private boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }

}
